package com.xl.yygh.user.api;

import com.alibaba.fastjson.JSONObject;
import com.netflix.ribbon.proxy.annotation.Http;
import com.xl.yygh.common.exception.YyghException;
import com.xl.yygh.common.helper.JwtHelper;
import com.xl.yygh.common.result.Result;
import com.xl.yygh.common.result.ResultCodeEnum;
import com.xl.yygh.model.model.user.UserInfo;
import com.xl.yygh.user.service.UserInfoService;
import com.xl.yygh.user.utils.ConstantWxPropertiesUtil;
import com.xl.yygh.user.utils.HttpClientUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @author XiangLiang
 * @date 2023/11/2 18:05
 * @description
 */
@Controller
@RequestMapping("/api/ucenter/wx")
public class WeixinApiController {
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 微信登录回调
     * @param code 临时票据
     * @param state 附加状态信息
     * @return
     */
    @GetMapping("/callback")
    public String callback (String code, String state) {
        //第一步 获取临时票据 code（参数中）
        System.out.println("code:"+code);
        if (StringUtils.isEmpty(state) || StringUtils.isEmpty(code)) {
            throw new YyghException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
        }

        //第二步 拿着code、微信id和秘钥，请求微信固定地址 ，得到两个值
        // 使用code、appid以及secret换取access_token
        StringBuffer baseAccessTokenUrl = new StringBuffer()
                .append("https://api.weixin.qq.com/sns/oauth2/access_token")
                .append("?appid=%s")
                .append("&secret=%s")
                .append("&code=%s")
                .append("&grant_type=authorization_code");
        String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
                ConstantWxPropertiesUtil.WX_OPEN_APP_ID,
                ConstantWxPropertiesUtil.WX_OPEN_APP_SECRET,
                code);

        // 使用httpclient请求这个地址
        String accessTokenInfo = null;;
        try {
            accessTokenInfo = HttpClientUtils.get(accessTokenUrl);
        } catch (Exception e) {
            throw new YyghException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
        }

        JSONObject accessTokenJsonObject = JSONObject.parseObject(accessTokenInfo);
        String accessToken = accessTokenJsonObject.getString("access_token");
        String openId = accessTokenJsonObject.getString("openid");

        // 根据openid查询数据库是否有对应记录
        UserInfo userInfo = userInfoService.getUserInfoByOpenId(openId);
        // 如果没有查到用户信息,那么调用微信个人信息获取的接口，并在数据库新建并存入用户
        if (userInfo == null) {
            // 使用access_token换取受保护的资源：微信的个人信息
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=%s" +
                    "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openId);
            String resultUserInfo = null;
            try {
                resultUserInfo = HttpClientUtils.get(userInfoUrl);
            } catch (Exception e) {
                throw new YyghException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
            }

            // 解析用户信息
            JSONObject resultUserInfoJson = JSONObject.parseObject(resultUserInfo);
            String nickName = resultUserInfoJson.getString("nickname");
            String headImgUrl = resultUserInfoJson.getString("headimgurl");

            // 存入新用户
            userInfo = new UserInfo();
            userInfo.setNickName(nickName);
            userInfo.setOpenid(openId);
            userInfo.setStatus(1);
            userInfoService.save(userInfo);
        }

        Map<String, Object> map = new HashMap<>();
        // 返回名字，优先级依次是 名字 > 昵称 > 电话
        String name = userInfo.getName();
        if (StringUtils.isEmpty(name)) {
            name = userInfo.getNickName();
        }
        if (StringUtils.isEmpty(name)) {
            name = userInfo.getPhone();
        }
        map.put("name", name);

        // 手机号空，返回openId；手机号不为空，openId返回为空字符串
        // 前端依此判断是否需要绑定手机号：openId不为空，需要绑定；openId为空，不需要绑定
        if (StringUtils.isEmpty(userInfo.getPhone())) {
            map.put("openid", userInfo.getOpenid());
        } else {
            map.put("openid", "");
        }

        String token = JwtHelper.createToken(userInfo.getId(), name);
        map.put("token", token);

        return "redirect:" + ConstantWxPropertiesUtil.YYGH_BASE_URL
                + "/weixin/callback?token=" + map.get("token") + "&openid=" + map.get("openid")
                + "&name=" + URLEncoder.encode((String)map.get("name"));
    }

    /**
     * 生成微信扫描二维码
     * 返回生成二维码所需参数
     */
    @GetMapping("getLoginParam")
    @ResponseBody
    public Result genQrConnect(HttpSession session)  {
        try {
            Map<String, Object> map = new HashMap<>();
            // appid、scope、redirect_uri为必要属性
            map.put("appid", ConstantWxPropertiesUtil.WX_OPEN_APP_ID);
            map.put("scope", "snsapi_login");
            String redirectUrl = ConstantWxPropertiesUtil.WX_OPEN_REDIRECT_URL;
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
            map.put("redirect_uri", redirectUrl);
            // 非必要
            map.put("state", System.currentTimeMillis() + "");
            return Result.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
